﻿package com.sgcc.nfc.lock.data.repository

import com.sgcc.nfc.lock.core.network.NetworkResult
import com.sgcc.nfc.lock.core.network.safeApiCall
import com.sgcc.nfc.lock.core.network.safeApiCallVoid
import com.sgcc.nfc.lock.data.local.dao.LockDao
import com.sgcc.nfc.lock.data.local.mapper.toDomain
import com.sgcc.nfc.lock.data.local.mapper.toEntity
import com.sgcc.nfc.lock.data.remote.api.LockApi
import com.sgcc.nfc.lock.data.remote.api.UpdateLockStatusRequest
import com.sgcc.nfc.lock.domain.model.Lock
import com.sgcc.nfc.lock.domain.model.PagedList
import com.sgcc.nfc.lock.domain.repository.LockRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.first

class LockRepositoryImpl @Inject constructor(
    private val lockApi: LockApi,
    private val lockDao: LockDao
) : LockRepository {

    override suspend fun getLocks(
        page: Int,
        pageSize: Int,
        roomId: Long?,
        status: Int?,
        keyword: String?,
        regionId: Long?
    ): NetworkResult<PagedList<Lock>> {
        val response = safeApiCall {
            lockApi.getLocks(page, pageSize, roomId, status, keyword, regionId)
        }
        return when (response) {
            is NetworkResult.Success -> {
                val paged = response.data.map { it.toDomain() }
                lockDao.upsertAll(paged.data.map { it.toEntity() })
                NetworkResult.Success(paged)
            }
            is NetworkResult.Error -> {
                val local = lockDao.observeLocks().first().map { it.toDomain() }
                if (local.isNotEmpty()) {
                    NetworkResult.Success(
                        PagedList(
                            data = local,
                            page = 1,
                            pageSize = local.size.toLong(),
                            total = local.size.toLong(),
                            pageCount = 1
                        )
                    )
                } else {
                    response
                }
            }
            NetworkResult.Loading -> NetworkResult.Loading
        }
    }

    override suspend fun getLockDetail(lockId: Long): NetworkResult<Lock> {
        val response = safeApiCall { lockApi.getLockDetail(lockId) }
        return when (response) {
            is NetworkResult.Success -> NetworkResult.Success(response.data.toDomain())
            is NetworkResult.Error -> response
            NetworkResult.Loading -> NetworkResult.Loading
        }
    }

    override suspend fun updateLockStatus(
        lockId: Long,
        status: Int,
        remark: String?
    ): NetworkResult<Unit> {
        return safeApiCallVoid {
            lockApi.updateStatus(lockId, UpdateLockStatusRequest(status, remark))
        }
    }

    override suspend fun addLock(lockNfcId: String, roomId: Long): NetworkResult<Unit> {
        return safeApiCallVoid {
            lockApi.addLock(lockNfcId, roomId)
        }
    }

    override suspend fun deleteLock(lockId: Long): NetworkResult<Unit> {
        return safeApiCallVoid {
            lockApi.deleteLock(lockId)
        }
    }
}
